Because that's how the language was designed!If a subunit redeclares a global identifier, then inside the subunit, both identifiers are in scope, but only the local identifier is visible. https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/plsql-language-fundamentals.html#GUID-2FC17012-FC99-4614-90DD-ADC99F2EDBE9
So local declarations always override those in the outer scope.
This avoids outer capture problems, where an identifier in local scope now resolves to one in the outer scope - e.g. if you declare a new object in the outer scope.
Because the local scope always has precedence, the only ways to access the outer object are to remove the inner declaration or fully qualify the reference to the outer object.
It also prevents possible problems if you use the same name for different objects in the inner and outer scope - e.g. a variable and a procedure:
same_name integer := 42;
procedure p as
procedure same_name as
dbms_output.put_line ( 'proc' );
dbms_output.put_line ( outer_block.same_name );