How does SELECT FOR UPDATE behave with views in PostgreSQL?
Short answer

The following rows will be locked for update in the three cases:


a row with "ID" = :ID in table "A" and all rows in table "B"
a row with "ID" = :ID in table "B" and all rows in table "A"
a row with "ID" = :ID1 in table "A" and a row with "ID" = :ID2 in table "B" 


The results are as one can expect after reading this statement in the documentation:


  If a locking clause is applied to a view or sub-query, it affects all tables used in the view or sub-query.


How to test similar cases

Install the extension pgrowlocks..

create extension if not exists pgrowlocks;


Run two instances of psql. In the first one start a transaction and execute a query.

psql #1:

begin;

select *
from "AB"
where "AID" = 3 and "BID" = 103
for update;


You can see locked rows in the other instance of psql.

psql #2:

select * from pgrowlocks('"B"');

 locked_row | locker | multi |  xids   |     modes      |  pids
------------+--------+-------+---------+----------------+--------
 (0,4)      |  88577 | f     | {88577} | {"For Update"} | {8068}
(1 row) 


Do not forget to close the transaction at the end (before a next test).

psql #1:

rollback;


The first column of the above result is ctid. You can select the original row with the query:

select *
from "B"
where ctid = '(0,4)';